package utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;

import utils.StringUtils.MyStringBuffer;
import domain.HowToNewInstance;

public class ObjectPool<O> {

	int intital_size = 5;
	
	Set<O> set_used = new HashSet<O>();
	
	List<O> list_idle = new ArrayList<O>();
	
	HowToNewInstance<O> htni;
	
	public ObjectPool(HowToNewInstance<O> htni){
		this.htni = htni;
		init();
	}
	
	private void init(){
		for(int i=0;i<intital_size;i++){
			O obj = htni.newInstance();
			list_idle.add(obj);
		}
	}
	
	private void addOneIdle(){
		list_idle.add(htni.newInstance());
	}
	
	public synchronized O get(){
		O One = null;
		
		if(list_idle.size()==0){
			addOneIdle();
		}
		
		One = list_idle.remove(0);
		set_used.add(One);
		
		return One;
	}
	
	public synchronized void returnBack(O obj){
		list_idle.add(obj);
	}
	
	public synchronized int getSizeInUse(){
		return set_used.size();
	}
	public synchronized int getSizeInIdle(){
		return list_idle.size();
	}
	
	public synchronized String listAll(){
		MyStringBuffer msb = StringUtils.getNewMyStringBuffer();
		msb.add("-InUse:").addEnter();
		for(O o : set_used){
			msb.add(Integer.toHexString(o.hashCode()).toUpperCase()).add(" - ").add(o.toString());
			msb.addEnter();
		}
		msb.add("-InIdle:").addEnter();
		for(O o : list_idle){
			msb.add(Integer.toHexString(o.hashCode()).toUpperCase()).add(" - ").add(o.toString());
			msb.addEnter();
		}
		return msb.getStringAndClose();
	}
	
	public static void main(String[] args) {
		ObjectPool<Calendar> pool = new ObjectPool<Calendar>(new HowToNewInstance<Calendar>() {
			public Calendar newInstance() {
				return Calendar.getInstance();
			}
		});
		
		System.out.println(pool.getSizeInIdle());
		System.out.println(pool.getSizeInUse());
		
		System.out.println(pool.listAll());
		
		Set<Calendar> set = new HashSet<Calendar>();
		
		for(int i=0;i<5;i++){
			Calendar cal = new GregorianCalendar();
			cal.setTimeInMillis(System.currentTimeMillis()+i);
			System.out.println(Integer.toHexString(cal.hashCode()).toUpperCase());
			set.add(cal);
		}
		System.out.println(set.size());
		
		System.out.println("---");
		System.out.println(TimeZone.getDefault().hashCode());
	}
}
